<script setup lang="ts">
import { SSEChat, SSEChatVoice } from "@/api/chat";
import { useUserStore } from "@/store/modules/user";
import storage from "@/utils/storage";
import sqls from "./utils/chat";
import Voice from "./components/Voice.vue";

const userStore = useUserStore();
const scrollTop = ref(0);
const scrollAnimationData = {};
const scrollWithAnimation = ref(false);
const scrollIntoID = ref<string>("chatID_0");
const msg = ref("");
const focus = ref(false);
const msgList = ref<ChatFace[]>([]);
const isSend = ref(false);
let animateId: number;
let sseArr = ref<string[]>([]);
const total = ref(0);
const inutType = ref("te22xt");
const listQuery = reactive<listQueryFace>({
  page: 1,
  size: 10,
});
const loading = ref<UniloadingFace>("loading");
const getList = (isbot = false) => {
  sqls.getList(listQuery).then((res) => {
    const newList = res.data.data;
    msgList.value.unshift(...newList);
    total.value = res.data.count;
    if (msgList.value.length >= total.value) {
      loading.value = "noMore";
    } else {
      loading.value = "more";
    }
    if (isbot) {
      scrollBottom();
    } else {
      const last = newList.pop();
      nextTick(() => {
        scrollIntoID.value = "chatId_" + last.id;
      });
    }
  });
};
getList(true);
/**
 * 兼容苹果，无法取到input的值
 * @param e
 */
const handleBlur = (e: FocusEvent) => {
  msg.value = e.detail.value;
};

const handleInput = (e: Event) => {
  msg.value = e.detail.value;
};
const onrefresh = function () {
  if (loading.value !== "more") return;
  loading.value = "loading";
  listQuery.page++;
  getList();
};
const handleScroll = (e) => {
  scrollTop.value = e.detail.scrollTop;
};
/**
 * 按钮发送
 */
const sendMsg = () => {
  // 略坑，苹果真机上textarea 无双向绑定，智能在blur时间后改变，故盐池提交
  setTimeout(() => {
    console.log("发送");
    console.log(msg);
    console.log(msg.value);
    if (msg.value != "") {
      console.log("发送消息");
      handleMsg(msg.value);
      msg.value = "";
    }
  }, 100);
};
const activeIndex = computed(() => {
  return msgList.value.length - 1;
});

const addMsg = (msg: string, type: ChatType = 2) => {
  const obj = sqls.addHistory(msg, type);
  msgList.value.push(obj);
  nextTick(() => {
    scrollBottom();
  });
};

const animate = () => {
  // #ifdef H5
  animateId = requestAnimationFrame(animate);
  if (sseArr.value.length !== 0) {
    msgList.value[activeIndex.value].msg += sseArr.value.shift();
    scrollBottom();
  } else {
    cancelAnimationFrame(animateId);
  }
  // #endif
  // #ifdef MP-WEIXIN
  animateId = setInterval(() => {
    if (sseArr.value.length !== 0) {
      msgList.value[activeIndex.value].msg += sseArr.value.splice(0, 1);
      console.log(msgList.value);
      scrollBottom();
    } else {
      clearInterval(animateId);
    }
  }, 50);
  // #endif
};

const handleMsg = (val: string) => {
  addMsg(val);
  addMsg("", 1);
  isSend.value = true;
  SSEChat({
    msg: val,
    callback: (val: string) => {
      sseArr.value.push(...val.split(""));
      animate();
    },
  })
    .then((res) => {
      sqls.update();
    })
    .catch((err) => {
      console.log(err);
    })
    .finally(() => {
      isSend.value = false;
    });
};

let timer: number;
const scrollBottom = () => {
  setTimeout(() => {
    if (scrollIntoID.value == "last-msg") {
      scrollIntoID.value = "";
      scrollBottom();
    } else {
      scrollIntoID.value = "last-msg";
    }
  }, 50);
};

const handleUpdateType = (str: string) => {
  inutType.value = str;
};
const handleSuccessVoice = (data: any) => {
  const datas = sqls.addHistory("", 2, data);
  console.log(datas);
  msgList.value.push(datas);

  const fileSystemManager = wx.getFileSystemManager();
  addMsg("", 1);
  const datass = fileSystemManager.readFile({
    filePath: data.voice, // 录音文件的路径
    encoding: "base64", // 指定编码为Base64
    success: function (res) {
      const base64Data = res.data; // 录音文件的Base64编码数据
      // 在这里进行下一步操作，例如将Base64数据上传到服务器或其他处理
      console.log(base64Data);
      SSEChatVoice({
        msg: base64Data,
        callback: (val) => {
          sseArr.value.push(...val.split(""));
          animate();
        },
      }).then(res=>{
        sqls.update();
      })
    },
    fail: function (err) {
      // 文件读取失败的处理逻辑
    },
  });

  scrollBottom();
};

onMounted(() => {
  console.log("到顶部");

  scrollBottom();
});
</script>

<template>
  <div class="chat-main nav-page">
    <div class="chat-container">
      <div class="chat-body">
        <scroll-view
          @scrolltoupper="onrefresh"
          :animation="scrollAnimationData"
          ref="scrollview"
          scroll-y="true"
          @scroll="handleScroll"
          class="chat-scroll"
          :scroll-into-view="scrollIntoID"
          :scroll-with-animation="false"
        >
          <li
            v-for="(item, index) in msgList"
            :id="'chatId_' + item.id"
            :key="item.id"
          >
            <Chatdetail :item="item" />
          </li>
          <div class="last_msg_item" id="last-msg"></div>
        </scroll-view>
      </div>
      <section class="chat-foot">
        <div class="chat-foot-body">
          <div class="chat-foot-left">
            <i
              v-if="inutType === 'text'"
              @click="handleUpdateType('vlid')"
              class="iconfont icon icon-yuyin"
            ></i>
            <i
              v-else
              @click="handleUpdateType('text')"
              class="iconfont icon icon-jianpan"
            ></i>
          </div>
          <div class="chat-foot-center">
            <textarea
              :maxlength="250"
              auto-height
              v-if="inutType === 'text'"
              :adjust-position="false"
              type="textarea"
              :show-confirm-bar="false"
              :value="msg"
              class="msg-input"
              @blur="handleBlur"
              @input="(e) => handleInput(e)"
              :focus="focus"
              placeholder=""
            />
            <div v-else>
              <Voice @success="handleSuccessVoice" class="msg-voice" />
            </div>
          </div>
          <div class="chat-foot-right">
            <view @click="sendMsg" v-if="msg" class="msg-btn"> 发送 </view>
          </div>
        </div>
      </section>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.chat-main {
}
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.chat-body {
  flex: 1;
  height: 0;
  overflow: hidden;
  .chat-scroll {
    height: 100%;
    background-color: #ededed;
    box-sizing: border-box;
    width: 100%;
  }
}
.chat-foot {
  background-color: transparent;

  transition: all 0.5s;
  &-body {
    display: flex;
    background-color: #f7f7f7;
    align-items: flex-end;
    padding: 20rpx;
    position: relative;
  }
  $height: 35px;
  $pd: 10rpx;
  &-left {
    $size: $height - 10;
    margin-right: 10px;
    height: $height;
    display: flex;
    align-items: center;
    justify-content: center;
    .icon {
      width: $size;
      height: $size;
      font-size: $size/1.5;
      text-align: center;
      border: 1px solid #333;
      display: inline-block;
      line-height: $size;
      border-radius: 50%;
    }
  }
  &-center {
    flex: 1;
  }
  &-right {
    margin-left: 10px;
  }

  .msg-input {
    background-color: #fff;
    /* #ifndef H5 */
    padding: 10rpx 20rpx;
    /* #endif */

    min-height: 65rpx;
    width: 100%;
    line-height: 45rpx;
    font-size: 30rpx;
    max-height: 200px;
    box-sizing: border-box;
  }
  ::v-deep .msg-voice {
    width: 100%;
    background-color: #fff;
    height: $height;
    text-align: center;
    line-height: $height;
  }
  .msg-btn {
    background-color: #21ba45;
    color: #fff;
    height: $height;
    line-height: $height;
    font-size: 26rpx;
    display: block;
    position: relative;
    padding: 0px 40rpx;
    z-index: 999;
    border-radius: 50rpx;
    background-image: linear-gradient(to left, #155bda, #5893fe);
  }
}
.last_msg_item {
  width: 100%;
  height: 20px;
}
</style>
